package server

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"websocket/utils"
)

type Hub struct {
	clients      map[*Client]bool
	registered   chan *Client
	unregistered chan *Client
	broadcast    chan []byte
	targetpush   chan *Msg `指定目标进行推送`
}

type SecretManager struct {
	manager string
	secret  []string
	del     chan []byte
	add     chan []byte
}

type Dispense struct {
	receiveUrl string
	send       chan []byte
}

func NewSecretManager(manager string, secret []string) *SecretManager {
	return &SecretManager{
		manager: manager,
		secret:  secret,
		del:     make(chan []byte, 128),
		add:     make(chan []byte, 128),
	}
}

func NewHub() *Hub {
	return &Hub{
		clients:      make(map[*Client]bool),
		registered:   make(chan *Client, 256),
		unregistered: make(chan *Client, 256),
		broadcast:    make(chan []byte, 256),
		targetpush:   make(chan *Msg, 512),
	}
}

func NewDispense(receiveUrl string) *Dispense {
	return &Dispense{
		receiveUrl: receiveUrl,
		send:       make(chan []byte, 1024),
	}
}

// 分发消息到指定的服务器，让第三方服务器接收用户消息
func (d *Dispense) Run() {
	for {
		select {
		case message := <-d.send:
			go func() {
				request, _ := http.NewRequest("POST", d.receiveUrl, strings.NewReader(string(message)))
				http.DefaultClient.Do(request)
			}()
		}
	}
}

func (hub *Hub) GetClientsByGroup(group string) []*Client {
	var res []*Client
	for h := range hub.clients {
		if h.group == group {
			res = append(res, h)
		}
	}

	return res
}

func (hub *Hub) Run() {
	for {
		select {
		case client := <-hub.registered:
			// 有新的连接来的时候
			hub.clients[client] = true
		case client := <-hub.unregistered:
			if _, ok := hub.clients[client]; ok {
				// 当连接断开的时候
				delete(hub.clients, client)
				// 关闭client下的send通道,会通知client.writeListener中去结束循环关闭链接
				close(client.send)
			}
		case message := <-hub.targetpush:
			msg, _ := json.Marshal(message)
			for _, client := range hub.GetClientsByGroup(message.Group) {
				select {
				case client.send <- msg:
				default:
					hub.unregistered <- client
				}
			}

		case message := <-hub.broadcast:
			// 广播信息
			for client := range hub.clients {
				// 向对应client发送消息,使用select default，不会阻塞
				select {
				// 向client发送massage
				case client.send <- message:
				default:
					// 如果执行default，阻塞了,send设置缓存256个长度 ，如果都执行了default，就认为发送message失败了
					// close 的时候会发送一个广播,使conn 关闭
					close(client.send)
					delete(hub.clients, client)
				}
			}
		}

	}
}

func (s *SecretManager) Run() {
	for {
		select {
		case ch := <-s.del:
			path, _ := os.Getwd()
			log := filepath.Join(path, "log//del.txt")
			utils.WriteLine(log, []string{string(ch)})
			s.delete(string(ch))
			fmt.Println("deleted：", s.secret)
		case ch := <-s.add:
			path, _ := os.Getwd()
			log := filepath.Join(path, "log//secret.txt")
			utils.WriteLine(log, []string{string(ch)})
			s.append(string(ch))
			fmt.Println("added：", s.secret)
		}
	}
}

func (s *SecretManager) isAdmin(user string) bool {
	if s.manager == user {
		return true
	}
	return false
}

func (s *SecretManager) delete(value string) []string {
	var temp []string
	for _, v := range s.secret {
		if v != value {
			temp = append(temp, v)
		}
	}
	s.secret = temp
	return temp
}

func (s *SecretManager) append(value string) []string {
	temp := append(s.secret, value)
	s.secret = temp
	return temp
}
